library(tidyverse)
tidyverse_logo()
* __  _    __   .    o           *  . 
 / /_(_)__/ /_ ___  _____ _______ ___ 
/ __/ / _  / // / |/ / -_) __(_-</ -_)
\__/_/\_,_/\_, /|___/\__/_/ /___/\__/ 
     *  . /___/      o      .       * 

if restarted R and just want one part or tidyverse

tidyverse::tidyverse_logo()
* __  _    __   .    o           *  . 
 / /_(_)__/ /_ ___  _____ _______ ___ 
/ __/ / _  / // / |/ / -_) __(_-</ -_)
\__/_/\_,_/\_, /|___/\__/_/ /___/\__/ 
     *  . /___/      o      .       * 
devtools::install_github("codeclan/CodeClanData")
WARNING: Rtools is required to build R packages, but is not currently installed.

Please download and install Rtools 4.0 from https://cran.r-project.org/bin/windows/Rtools/.
Skipping install of 'CodeClanData' from a github remote, the SHA1 (d46cb3c5) has not changed since last install.
  Use `force = TRUE` to force installation
library(CodeClanData)
students

Working with dplyr

all_deaths

#checking our data

#number of rows
nrow(all_deaths)
[1] 917
#number of colums
ncol(all_deaths)
[1] 13
# overall dimensions
dim(all_deaths)
[1] 917  13
# variable names
names(all_deaths)
 [1] "name"               "allegiances"        "year_of_death"      "book_of_death"     
 [5] "death_chapter"      "book_intro_chapter" "gender"             "nobility"          
 [9] "book1_GoT"          "book2_CoK"          "book3_SoS"          "book4_FfC"         
[13] "book5_DwD"         
# check the first 10 rows
head(all_deaths, 10)
# check the last 10
tail(all_deaths, 10)
# get an overveiw of the data
glimpse(all_deaths)
Rows: 917
Columns: 13
$ name               <chr> "Addam Marbrand", "Aegon Frey (Jinglebell)", "Aegon Targaryen", "Adrack Hum~
$ allegiances        <chr> "Lannister", "None", "House Targaryen", "House Greyjoy", "Lannister", "Bara~
$ year_of_death      <dbl> NA, 299, NA, 300, NA, NA, 300, 300, NA, NA, 299, NA, 300, NA, NA, NA, 299, ~
$ book_of_death      <dbl> NA, 3, NA, 5, NA, NA, 4, 5, NA, NA, 2, NA, 5, NA, NA, NA, 2, NA, NA, 4, NA,~
$ death_chapter      <dbl> NA, 51, NA, 20, NA, NA, 35, NA, NA, NA, 56, NA, 4, NA, NA, NA, 46, NA, NA, ~
$ book_intro_chapter <dbl> 56, 49, 5, 20, NA, NA, 21, 59, 11, 0, 50, 54, 18, 15, 38, 26, 4, 6, 65, 36,~
$ gender             <dbl> 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, ~
$ nobility           <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, ~
$ book1_GoT          <dbl> 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, ~
$ book2_CoK          <dbl> 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, ~
$ book3_SoS          <dbl> 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, ~
$ book4_FfC          <dbl> 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, ~
$ book5_DwD          <dbl> 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, ~
# view data
view(all_deaths)
#view a shirt representation of the data
str(all_deaths)
spec_tbl_df [917 x 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ name              : chr [1:917] "Addam Marbrand" "Aegon Frey (Jinglebell)" "Aegon Targaryen" "Adrack Humble" ...
 $ allegiances       : chr [1:917] "Lannister" "None" "House Targaryen" "House Greyjoy" ...
 $ year_of_death     : num [1:917] NA 299 NA 300 NA NA 300 300 NA NA ...
 $ book_of_death     : num [1:917] NA 3 NA 5 NA NA 4 5 NA NA ...
 $ death_chapter     : num [1:917] NA 51 NA 20 NA NA 35 NA NA NA ...
 $ book_intro_chapter: num [1:917] 56 49 5 20 NA NA 21 59 11 0 ...
 $ gender            : num [1:917] 1 1 1 1 1 1 1 0 1 1 ...
 $ nobility          : num [1:917] 1 1 1 1 1 1 1 1 1 0 ...
 $ book1_GoT         : num [1:917] 1 0 0 0 0 0 1 1 0 0 ...
 $ book2_CoK         : num [1:917] 1 0 0 0 0 1 0 1 1 0 ...
 $ book3_SoS         : num [1:917] 1 1 0 0 1 1 1 1 0 1 ...
 $ book4_FfC         : num [1:917] 1 0 0 0 0 0 1 0 1 0 ...
 $ book5_DwD         : num [1:917] 0 0 1 1 0 0 0 1 0 0 ...
 - attr(*, "spec")=
  .. cols(
  ..   name = col_character(),
  ..   allegiances = col_character(),
  ..   year_of_death = col_double(),
  ..   book_of_death = col_double(),
  ..   death_chapter = col_double(),
  ..   book_intro_chapter = col_double(),
  ..   gender = col_double(),
  ..   nobility = col_double(),
  ..   book1_GoT = col_double(),
  ..   book2_CoK = col_double(),
  ..   book3_SoS = col_double(),
  ..   book4_FfC = col_double(),
  ..   book5_DwD = col_double()
  .. )
# print data in the console
all_deaths

Select()

# selecting a few variables to keep
select(all_deaths, name, allegiances, gender, nobility, year_of_death)
# can remove a colum if needed
select(all_deaths, -name)
# making a var 
death_no_names <- select(all_deaths, -name)
books <- select(all_deaths, 4, 6, 9:13)
books
books_anotherway <- select(all_deaths, 4, 6, book1_GoT:book5_DwD)
books_anotherway
god <- select(all_deaths, contains("book"))
god
deaths <- select(all_deaths, 3:5)
deaths

filter()

filter(all_deaths, allegiances == "Lannister")
# found 102 rows
filter(all_deaths, allegiances == "Lannister" | 
         allegiances == "House Lannister")
filter(all_deaths, allegiances != "Lannister")
filter(all_deaths, allegiances %in% c("House Lannister", 
                                      "Lannister"))
filter(all_deaths, year_of_death >= 299)
filter(all_deaths, allegiances == "None")
filter(all_deaths, book_intro_chapter >= 5 & 
         book_intro_chapter <= 10)

#Tast 1 Find where the year_of_deathis less than or equal to 299.

filter(all_deaths, year_of_death <= 299)

#Tast 2 Find the females (gender is 0) who are not Lannisters

filter(all_deaths, gender == 0 & allegiances != "Lannister")

#Tast 3 Find just the data for the characters “Jon Snow”, “Daenerys Targaryen” and “Samwell Tarly”.

filter(all_deaths, name == "Jon Snow" |
           name == "Daenerys Targaryen" |
           name == "Samwell Tarly")

another way

filter(all_deaths, name %in% c("Jon Snow",
                               "Daenerys Targaryen",
                               "Samwell Tarly"))

Arrange

arrange(all_deaths, gender)
arrange(all_deaths, desc(gender))
arrange(all_deaths, book_of_death, death_chapter)

#Arrange all_deaths by allegiances. What happens when you arrange by a character column?

arrange(all_deaths, allegiances)

#Arrange all_deaths by allegiances and book_intro_chapter

arrange(all_deaths, allegiances, book_intro_chapter)

#Arrange all_deaths by descending year_of_death

arrange(all_deaths, desc(year_of_death))

mutate()

# To make a new var/change a var
mutate(all_deaths, years_survived = year_of_death - 298)
mutate(all_deaths, book_of_death = book_of_death * 5)
mutate(all_deaths, year_of_death = is.na(year_of_death))
# changes year_of_death from dbl to a Lgl
mutate(all_deaths, book_of_death = as.character(book_of_death))
mutate(all_deaths, name = as.numeric(name))
Warning: Problem with `mutate()` column `name`.
i `name = as.numeric(name)`.
i NAs introduced by coercion
mutate(all_deaths, year_of_death = sum(year_of_death, na.rm = TRUE))
mutate( all_deaths, year_of_death = mean(year_of_death, na.rm = TRUE))

Summarise

summarise(all_deaths, n_males = sum(gender))
death_grouped <- group_by(all_deaths, allegiances)
death_grouped
# is the background Groups:allegiances [21]
summarise(death_grouped, character_count = n())
death_grouped <- group_by(all_deaths, nobility, gender)
summarise(death_grouped, character_count = n())
`summarise()` has grouped output by 'nobility'. You can override using the `.groups` argument.

magrittr pipes

# find the people taht have died
have_died <- filter(all_deaths, !is.na(book_of_death))

died_grouped <-  group_by(have_died, allegiances)

died_counts <- summarise(died_grouped, count = n())

arrange(died_counts, desc(count))
# takes the line before the %>% and places as the first argument
all_deaths %>%
  filter(!is.na(book_of_death)) %>%
  group_by(allegiances) %>%
  summarise(count = n()) %>%
  arrange(desc(count))
# docent need to make mutual var
death_by_allegiance <- all_deaths %>%
                            filter(!is.na(book_of_death)) %>%
                            group_by(allegiances) %>%
                            summarise(count = n()) %>%
                            arrange(desc(count))

Pull

av_year_of_death <- all_deaths %>%
  summarise(av_value = mean(year_of_death, 
                            na.rm = TRUE))

av_year_of_death
all_deaths %>%
  mutate(death_later_than_av = year_of_death >
           av_year_of_death)
all_deaths %>%
  mutate(death_later_than_av = year_of_death >
           299.1574)
class(av_year_of_death)
[1] "numeric"
class(299.1574)
[1] "numeric"
av_year_of_death <- all_deaths %>%
  summarise(av_value = mean(year_of_death, 
                            na.rm = TRUE)) %>%
  pull()

av_year_of_death
[1] 299.1574
all_deaths %>%
  mutate(death_later_than_av = year_of_death >
           av_year_of_death)
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KYGBgDQoNCmBgYHtyfQ0KdGlkeXZlcnNlX2xvZ28oKQ0KYGBgDQojIGlmIHJlc3RhcnRlZCBSIGFuZCBqdXN0IHdhbnQgb25lIHBhcnQgb3IgdGlkeXZlcnNlDQpgYGB7cn0NCnRpZHl2ZXJzZTo6dGlkeXZlcnNlX2xvZ28oKQ0KYGBgDQoNCmBgYHtyfQ0KZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJjb2RlY2xhbi9Db2RlQ2xhbkRhdGEiKQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShDb2RlQ2xhbkRhdGEpDQpgYGANCg0KYGBge3J9DQpzdHVkZW50cw0KYGBgDQojIFdvcmtpbmcgd2l0aCBkcGx5cg0KYGBge3J9DQphbGxfZGVhdGhzDQpgYGANCiNjaGVja2luZyBvdXIgZGF0YQ0KYGBge3J9DQojbnVtYmVyIG9mIHJvd3MNCm5yb3coYWxsX2RlYXRocykNCmBgYA0KDQpgYGB7cn0NCiNudW1iZXIgb2YgY29sdW1zDQpuY29sKGFsbF9kZWF0aHMpDQpgYGANCg0KYGBge3J9DQojIG92ZXJhbGwgZGltZW5zaW9ucw0KZGltKGFsbF9kZWF0aHMpDQpgYGANCg0KYGBge3J9DQojIHZhcmlhYmxlIG5hbWVzDQpuYW1lcyhhbGxfZGVhdGhzKQ0KYGBgDQoNCmBgYHtyfQ0KIyBjaGVjayB0aGUgZmlyc3QgMTAgcm93cw0KaGVhZChhbGxfZGVhdGhzLCAxMCkNCmBgYA0KDQpgYGB7cn0NCiMgY2hlY2sgdGhlIGxhc3QgMTANCnRhaWwoYWxsX2RlYXRocywgMTApDQpgYGANCg0KYGBge3J9DQojIGdldCBhbiBvdmVydmVpdyBvZiB0aGUgZGF0YQ0KZ2xpbXBzZShhbGxfZGVhdGhzKQ0KYGBgDQoNCmBgYHtyfQ0KIyB2aWV3IGRhdGENCnZpZXcoYWxsX2RlYXRocykNCmBgYA0KDQpgYGB7cn0NCiN2aWV3IGEgc2hpcnQgcmVwcmVzZW50YXRpb24gb2YgdGhlIGRhdGENCnN0cihhbGxfZGVhdGhzKQ0KYGBgDQoNCmBgYHtyfQ0KIyBwcmludCBkYXRhIGluIHRoZSBjb25zb2xlDQphbGxfZGVhdGhzDQpgYGANCg0KIyBTZWxlY3QoKQ0KYGBge3J9DQojIHNlbGVjdGluZyBhIGZldyB2YXJpYWJsZXMgdG8ga2VlcA0Kc2VsZWN0KGFsbF9kZWF0aHMsIG5hbWUsIGFsbGVnaWFuY2VzLCBnZW5kZXIsIG5vYmlsaXR5LCB5ZWFyX29mX2RlYXRoKQ0KYGBgDQoNCmBgYHtyfQ0KIyBjYW4gcmVtb3ZlIGEgY29sdW0gaWYgbmVlZGVkDQpzZWxlY3QoYWxsX2RlYXRocywgLW5hbWUpDQpgYGANCg0KYGBge3J9DQojIG1ha2luZyBhIHZhciANCmRlYXRoX25vX25hbWVzIDwtIHNlbGVjdChhbGxfZGVhdGhzLCAtbmFtZSkNCmBgYA0KDQpgYGB7cn0NCiNwYXJ0IG9mIGEgdGFzdA0KYm9va3MgPC0gc2VsZWN0KGFsbF9kZWF0aHMsIDQsIDYsIDk6MTMpDQpib29rcw0KYGBgDQpgYGB7cn0NCiMgZGlmZmVyZW50IHdheQ0KYm9va3NfYW5vdGhlcndheSA8LSBzZWxlY3QoYWxsX2RlYXRocywgNCwgNiwgYm9vazFfR29UOmJvb2s1X0R3RCkNCmJvb2tzX2Fub3RoZXJ3YXkNCmBgYA0KDQoNCmBgYHtyfQ0KIyBhbm90aGVyd2F5IHRvIGRvIGl0DQpnb2QgPC0gc2VsZWN0KGFsbF9kZWF0aHMsIGNvbnRhaW5zKCJib29rIikpDQpnb2QNCmBgYA0KDQoNCg0KYGBge3J9DQpkZWF0aHMgPC0gc2VsZWN0KGFsbF9kZWF0aHMsIDM6NSkNCmRlYXRocw0KYGBgDQojIGZpbHRlcigpDQoNCmBgYHtyfQ0KIyBmb3VuZCA4MSByb3dzDQpmaWx0ZXIoYWxsX2RlYXRocywgYWxsZWdpYW5jZXMgPT0gIkxhbm5pc3RlciIpDQpgYGANCg0KDQpgYGB7cn0NCiMgZm91bmQgMTAyIHJvd3MNCmZpbHRlcihhbGxfZGVhdGhzLCBhbGxlZ2lhbmNlcyA9PSAiTGFubmlzdGVyIiB8IA0KICAgICAgICAgYWxsZWdpYW5jZXMgPT0gIkhvdXNlIExhbm5pc3RlciIpDQpgYGANCg0KYGBge3J9DQojIGZpbmVzIGFsbCB0aGUgb3RoZXIgYWxsZWdpYW5jZXMNCmZpbHRlcihhbGxfZGVhdGhzLCBhbGxlZ2lhbmNlcyAhPSAiTGFubmlzdGVyIikNCmBgYA0KDQpgYGB7cn0NCiMgc2FtZSBhcyB0d28gYWJvdmUNCmZpbHRlcihhbGxfZGVhdGhzLCBhbGxlZ2lhbmNlcyAlaW4lIGMoIkhvdXNlIExhbm5pc3RlciIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGFubmlzdGVyIikpDQpgYGANCg0KYGBge3J9DQpmaWx0ZXIoYWxsX2RlYXRocywgeWVhcl9vZl9kZWF0aCA+PSAyOTkpDQpgYGANCg0KYGBge3J9DQpmaWx0ZXIoYWxsX2RlYXRocywgYWxsZWdpYW5jZXMgPT0gIk5vbmUiKQ0KYGBgDQoNCmBgYHtyfQ0KZmlsdGVyKGFsbF9kZWF0aHMsIGJvb2tfaW50cm9fY2hhcHRlciA+PSA1ICYgDQogICAgICAgICBib29rX2ludHJvX2NoYXB0ZXIgPD0gMTApDQpgYGANCg0KI1Rhc3QgMSBGaW5kIHdoZXJlIHRoZSB5ZWFyX29mX2RlYXRoaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDI5OS4NCmBgYHtyfQ0KZmlsdGVyKGFsbF9kZWF0aHMsIHllYXJfb2ZfZGVhdGggPD0gMjk5KQ0KYGBgDQoNCiNUYXN0IDIgRmluZCB0aGUgZmVtYWxlcyAoZ2VuZGVyIGlzIDApIHdobyBhcmUgbm90IExhbm5pc3RlcnMNCmBgYHtyfQ0KZmlsdGVyKGFsbF9kZWF0aHMsIGdlbmRlciA9PSAwICYgYWxsZWdpYW5jZXMgIT0gIkxhbm5pc3RlciIpDQpgYGANCg0KI1Rhc3QgMyBGaW5kIGp1c3QgdGhlIGRhdGEgZm9yIHRoZSBjaGFyYWN0ZXJzIOKAnEpvbiBTbm934oCdLCDigJxEYWVuZXJ5cyBUYXJnYXJ5ZW7igJ0gYW5kIOKAnFNhbXdlbGwgVGFybHnigJ0uDQpgYGB7cn0NCmZpbHRlcihhbGxfZGVhdGhzLCBuYW1lID09ICJKb24gU25vdyIgfA0KICAgICAgICAgICBuYW1lID09ICJEYWVuZXJ5cyBUYXJnYXJ5ZW4iIHwNCiAgICAgICAgICAgbmFtZSA9PSAiU2Ftd2VsbCBUYXJseSIpDQpgYGANCg0KIyBhbm90aGVyIHdheQ0KYGBge3J9DQpmaWx0ZXIoYWxsX2RlYXRocywgbmFtZSAlaW4lIGMoIkpvbiBTbm93IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGFlbmVyeXMgVGFyZ2FyeWVuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2Ftd2VsbCBUYXJseSIpKQ0KYGBgDQoNCiMgQXJyYW5nZQ0KYGBge3J9DQojIGFycmFuZ2UgYnkgZ2VuZGVyLCBsb3cgbnVtYmVyIGZpcnN0IGFjY2VudGluZw0KYXJyYW5nZShhbGxfZGVhdGhzLCBnZW5kZXIpDQpgYGANCg0KYGBge3J9DQojIGFycmFuZ2UgYnkgZ2VuZGVyIG1hbGUgZmlyc3QNCmFycmFuZ2UoYWxsX2RlYXRocywgZGVzYyhnZW5kZXIpKQ0KYGBgDQoNCmBgYHtyfQ0KIyBhcnJhbmdlZCBieSBib29rIHRoZW4gY2hhcHRlcg0KYXJyYW5nZShhbGxfZGVhdGhzLCBib29rX29mX2RlYXRoLCBkZWF0aF9jaGFwdGVyKQ0KYGBgDQoNCiNBcnJhbmdlIGFsbF9kZWF0aHMgYnkgYWxsZWdpYW5jZXMuIFdoYXQgaGFwcGVucyB3aGVuIHlvdSBhcnJhbmdlIGJ5IGEgY2hhcmFjdGVyIGNvbHVtbj8NCmBgYHtyfQ0KYXJyYW5nZShhbGxfZGVhdGhzLCBhbGxlZ2lhbmNlcykNCmBgYA0KDQojQXJyYW5nZSBhbGxfZGVhdGhzIGJ5IGFsbGVnaWFuY2VzIGFuZCBib29rX2ludHJvX2NoYXB0ZXINCmBgYHtyfQ0KYXJyYW5nZShhbGxfZGVhdGhzLCBhbGxlZ2lhbmNlcywgYm9va19pbnRyb19jaGFwdGVyKQ0KYGBgDQoNCiNBcnJhbmdlIGFsbF9kZWF0aHMgYnkgZGVzY2VuZGluZyB5ZWFyX29mX2RlYXRoDQpgYGB7cn0NCmFycmFuZ2UoYWxsX2RlYXRocywgZGVzYyh5ZWFyX29mX2RlYXRoKSkNCmBgYA0KDQojIG11dGF0ZSgpDQpgYGB7cn0NCiMgVG8gbWFrZSBhIG5ldyB2YXIvY2hhbmdlIGEgdmFyDQptdXRhdGUoYWxsX2RlYXRocywgeWVhcnNfc3Vydml2ZWQgPSB5ZWFyX29mX2RlYXRoIC0gMjk4KQ0KIyBQZW9wbGUgc3RpbGwgYWxpdmUgaGF2ZSBub3QgYmVlbiBjb3VudGVkIGFzIE4vQSAtIDI5OCBpcyBOL0ENCmBgYA0KDQpgYGB7cn0NCiMgY2hhbmdlIHRoZSB2YXINCm11dGF0ZShhbGxfZGVhdGhzLCBib29rX29mX2RlYXRoID0gYm9va19vZl9kZWF0aCAqIDUpDQpgYGANCg0KYGBge3J9DQptdXRhdGUoYWxsX2RlYXRocywgeWVhcl9vZl9kZWF0aCA9IGlzLm5hKHllYXJfb2ZfZGVhdGgpKQ0KIyBjaGFuZ2VzIHllYXJfb2ZfZGVhdGggZnJvbSBkYmwgdG8gYSBMZ2wgInRydWUvZmFsc2UiDQpgYGANCg0KYGBge3J9DQptdXRhdGUoYWxsX2RlYXRocywgYm9va19vZl9kZWF0aCA9IGFzLmNoYXJhY3Rlcihib29rX29mX2RlYXRoKSkNCiMgY2hhbmdlZCB0eXBlIHRvIGNoYXJhY3Rlcg0KYGBgDQoNCmBgYHtyfQ0KbXV0YXRlKGFsbF9kZWF0aHMsIG5hbWUgPSBhcy5udW1lcmljKG5hbWUpKQ0KIyBnaXZlIHdhcm5pbmcgYXMgaXQncyBoYWQgdG8gYWRkIE4vQSB0byB0aGUgbGlzdA0KYGBgDQoNCmBgYHtyfQ0KbXV0YXRlKGFsbF9kZWF0aHMsIHllYXJfb2ZfZGVhdGggPSBzdW0oeWVhcl9vZl9kZWF0aCwgbmEucm0gPSBUUlVFKSkNCmBgYA0KDQpgYGB7cn0NCm11dGF0ZSggYWxsX2RlYXRocywgeWVhcl9vZl9kZWF0aCA9IG1lYW4oeWVhcl9vZl9kZWF0aCwgbmEucm0gPSBUUlVFKSkNCmBgYA0KDQojIFN1bW1hcmlzZQ0KYGBge3J9DQpzdW1tYXJpc2UoYWxsX2RlYXRocywgbl9tYWxlcyA9IHN1bShnZW5kZXIpKQ0KYGBgDQoNCmBgYHtyfQ0KZGVhdGhfZ3JvdXBlZCA8LSBncm91cF9ieShhbGxfZGVhdGhzLCBhbGxlZ2lhbmNlcykNCmRlYXRoX2dyb3VwZWQNCiMgaXMgdGhlIGJhY2tncm91bmQgR3JvdXBzOmFsbGVnaWFuY2VzIFsyMV0NCnN1bW1hcmlzZShkZWF0aF9ncm91cGVkLCBjaGFyYWN0ZXJfY291bnQgPSBuKCkpDQpgYGANCg0KYGBge3J9DQpkZWF0aF9ncm91cGVkIDwtIGdyb3VwX2J5KGFsbF9kZWF0aHMsIG5vYmlsaXR5LCBnZW5kZXIpDQpzdW1tYXJpc2UoZGVhdGhfZ3JvdXBlZCwgY2hhcmFjdGVyX2NvdW50ID0gbigpKQ0KYGBgDQoNCiMgbWFncml0dHIgcGlwZXMNCmBgYHtyfQ0KIyBmaW5kIHRoZSBwZW9wbGUgdGhhdCBoYXZlIGRpZWQgd2l0aG91dCBwaXBlcw0KaGF2ZV9kaWVkIDwtIGZpbHRlcihhbGxfZGVhdGhzLCAhaXMubmEoYm9va19vZl9kZWF0aCkpDQoNCmRpZWRfZ3JvdXBlZCA8LSAgZ3JvdXBfYnkoaGF2ZV9kaWVkLCBhbGxlZ2lhbmNlcykNCg0KZGllZF9jb3VudHMgPC0gc3VtbWFyaXNlKGRpZWRfZ3JvdXBlZCwgY291bnQgPSBuKCkpDQoNCmFycmFuZ2UoZGllZF9jb3VudHMsIGRlc2MoY291bnQpKQ0KYGBgDQoNCmBgYHtyfQ0KIyB0YWtlcyB0aGUgbGluZSBiZWZvcmUgdGhlICU+JSBhbmQgcGxhY2VzIGFzIHRoZSBmaXJzdCBhcmd1bWVudA0KYWxsX2RlYXRocyAlPiUNCiAgZmlsdGVyKCFpcy5uYShib29rX29mX2RlYXRoKSkgJT4lDQogIGdyb3VwX2J5KGFsbGVnaWFuY2VzKSAlPiUNCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUNCiAgYXJyYW5nZShkZXNjKGNvdW50KSkNCiMgZG9jZW50IG5lZWQgdG8gbWFrZSBtdXR1YWwgdmFyDQpgYGANCg0KYGBge3J9DQpkZWF0aF9ieV9hbGxlZ2lhbmNlIDwtIGFsbF9kZWF0aHMgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKCFpcy5uYShib29rX29mX2RlYXRoKSkgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoYWxsZWdpYW5jZXMpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYW5nZShkZXNjKGNvdW50KSkNCmBgYA0KDQojIFB1bGwNCmBgYHtyfQ0KYXZfeWVhcl9vZl9kZWF0aCA8LSBhbGxfZGVhdGhzICU+JQ0KICBzdW1tYXJpc2UoYXZfdmFsdWUgPSBtZWFuKHllYXJfb2ZfZGVhdGgsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hLnJtID0gVFJVRSkpDQoNCmF2X3llYXJfb2ZfZGVhdGgNCiMgVGhpcyBtYWtlcyBhIHRhYmxlIGNhbiBiZSBoYXJkIHRvIHVzZQ0KYGBgDQoNCmBgYHtyfQ0KYWxsX2RlYXRocyAlPiUNCiAgbXV0YXRlKGRlYXRoX2xhdGVyX3RoYW5fYXYgPSB5ZWFyX29mX2RlYXRoID4NCiAgICAgICAgICAgYXZfeWVhcl9vZl9kZWF0aCkNCiMgVGhpcyBpcyB3aGF0IHdlIHdhbnQgdG8gd29yayBidXQgaXRzIG5vdCB3b3JrZWQsIHdlJ3JlIGdpdmluZyBpdCBhIHRhYmxlIHdoZW4gaXQgd2FudHMgYSBudW1iZXINCmBgYA0KDQpgYGB7cn0NCmFsbF9kZWF0aHMgJT4lDQogIG11dGF0ZShkZWF0aF9sYXRlcl90aGFuX2F2ID0geWVhcl9vZl9kZWF0aCA+DQogICAgICAgICAgIDI5OS4xNTc0KQ0KIyBUaGlzIHdvcmtzIGJ1dCBpZiB0aGUgZGF0YSBpcyBhZGRlZCB0byB0aGUgbnVtYmVyIHdpbGwgY2hhbmdlIGFuZCB0aGlzIHdvbnQgd29yaw0KYGBgDQoNCmBgYHtyfQ0KIyBMZXQncyB5b3UgZmluZSB3aGF0IHR5cGUgdGhlIGRhdGEgaXMNCmNsYXNzKGF2X3llYXJfb2ZfZGVhdGgpDQpjbGFzcygyOTkuMTU3NCkNCmBgYA0KDQoNCg0KYGBge3J9DQphdl95ZWFyX29mX2RlYXRoIDwtIGFsbF9kZWF0aHMgJT4lDQogIHN1bW1hcmlzZShhdl92YWx1ZSA9IG1lYW4oeWVhcl9vZl9kZWF0aCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEucm0gPSBUUlVFKSkgJT4lDQogIHB1bGwoKQ0KDQphdl95ZWFyX29mX2RlYXRoDQoNCmBgYA0KDQpgYGB7cn0NCmFsbF9kZWF0aHMgJT4lDQogIG11dGF0ZShkZWF0aF9sYXRlcl90aGFuX2F2ID0geWVhcl9vZl9kZWF0aCA+DQogICAgICAgICAgIGF2X3llYXJfb2ZfZGVhdGgpDQpgYGANCg0K